/*--------------------------------------------------------------------------
    This source file is part of Abraxas Game Engine
    For the latest info, see http://code.google.com/abraxasge/
    Copyright (C) 2009, Andrew LeRoy <aleroy@member.igda.org>
    ---

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA  02110-1301, USA.
--------------------------------------------------------------------------*/
#ifndef _Abx_String_hpp_
#define _Abx_String_hpp_

#include "AbxPrerequisites.hpp"

// If we're using the GCC 3.1 C++ Std lib
#if ABX_COMPILER == ABX_COMPILER_GNUC && ABX_COMP_VER >= 310 && !defined(STLPORT)

// For gcc 4.3 see http://gcc.gnu.org/gcc-4.3/changes.html
#   if ABX_COMP_VER >= 430
#       include <tr1/unordered_map> 
#   else
#       include <ext/hash_map>
namespace __gnu_cxx
{
    template <> struct hash< Abx::_StringBase >
    {
        size_t operator()( const Abx::_StringBase _stringBase ) const
        {
            /* This is the PRO-STL way, but it seems to cause problems with VC7.1
               and in some other cases (although I can't recreate it)
            hash<const char*> H;
            return H(_stringBase.c_str());
            */
            /** This is how OGRE does it */
            register size_t ret = 0;
            for( Abx::_StringBase::const_iterator it = _stringBase.begin(); it != _stringBase.end(); ++it )
                ret = 5 * ret + *it;

            return ret;
        }
    };
} // namespace __gnu_cxx
#   endif
#endif


namespace Abx
{
    template <class T>
    inline String to_string (T const& t)
    {
        std::stringstream ss;
        ss << t;
        return ss.str();
    };


    class _AbxExport StringTools
    {
      public: // TYPES
        typedef ::std::ostringstream StrStreamType;
        
      public: // C'STOR / D'STOR
        StringTools() { };
        ~StringTools() { };
        
      public: // DATA
        static String const BLANK;
    };



    #if ABX_COMPILER == ABX_COMPILER_GNUC && ABX_COMP_VER >= 310 && !defined(STLPORT)
    #   if ABX_COMP_VER < 430
        typedef ::__gnu_cxx::hash< _StringBase > _StringHash;
    #   else
        typedef ::std::tr1::hash< _StringBase > _StringHash;
    #   endif
    #elif !defined( _STLP_HASH_FUN_H )
        typedef stdext::hash_compare< _StringBase, std::less< _StringBase > > _StringHash;
    #else
        typedef std::hash< _StringBase > _StringHash;
    #endif 
} // namespace Abx



#endif // _Abx_AbxString_hpp_
